/*
 * $Id: GHOST_WindowX11.cpp 35771 2011-03-25 05:23:58Z campbellbarton $
 * ***** BEGIN GPL LICENSE BLOCK *****
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
 * All rights reserved.
 *
 * The Original Code is: all of this file.
 *
 * Contributor(s): none yet.
 *
 * ***** END GPL LICENSE BLOCK *****
 */

/** \file ghost/intern/GHOST_WindowX11.cpp
 *  \ingroup GHOST
 */


#include "GHOST_WindowX11.h"
#include "GHOST_SystemX11.h"
#include "STR_String.h"
#include "GHOST_Debug.h"

// For standard X11 cursors
#include <X11/cursorfont.h>
#include <X11/Xatom.h>

#if defined(__sun__) || defined( __sun ) || defined (__sparc) || defined (__sparc__) || defined (_AIX)
#include <strings.h>
#endif

#include <cstring>
#include <cstdio>

#include <algorithm>
#include <string>

// For obscure full screen mode stuuf
// lifted verbatim from blut.

typedef struct {
	long flags;
	long functions;
	long decorations;
	long input_mode;
} MotifWmHints;

#define MWM_HINTS_DECORATIONS         (1L << 1)


// #define GHOST_X11_GRAB

/*
 * A Client can't change the window property, that is
 * the work of the window manager. In case, we send
 * a ClientMessage to the RootWindow with the property
 * and the Action (WM-spec define this):
 */
#define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1
#define _NET_WM_STATE_TOGGLE 2

/*
import bpy
I = bpy.data.images['blender.png'] # the 48x48 icon

# Write to a file that can be 
# used within static unsigned char BLENDER_ICON_48x48x24[] = {...}
f = open('/myicon.txt', 'w')
for j in xrange(48):
        for k in xrange(48):
                v = I.getPixelI(j,47-k)
                v.pop()
                for p in v:
                        f.write(str(hex(p))+',')

        f.write('\n')
*/

// See the python script above to regenerate the 48x48 icon within blender
#define BLENDER_ICON_WIDTH 48
#define BLENDER_ICON_HEIGHT 48
static unsigned char BLENDER_ICON_48x48x24[] = {
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x4f,0x2a,0xd,0xa7,0x5b,0x1f,0xb8,0x66,0x22,0x6c,0x3b,0x14,0x5,0x3,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x6f,0x3a,0x13,0xea,0x7f,0x2c,0xee,0x7e,0x2b,0xee,0x7e,0x2b,0xef,0x85,0x2e,0x5f,0x35,0x12,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x43,0x22,0xb,0xed,0x7f,0x2c,0xed,0x7c,0x2b,0xee,0x7f,0x2c,0xee,0x80,0x2c,0xee,0x80,0x2c,0xa8,0x5f,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x2e,0x16,0x6,0xd0,0x6f,0x26,0xed,0x7b,0x2a,0xed,0x7d,0x2b,0xee,0x7f,0x2c,0xee,0x80,0x2c,0xee,0x82,0x2d,0x9a,0x57,0x1d,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x17,0xb,0x4,0xb9,0x60,0x21,0xed,0x7a,0x2a,0xed,0x7b,0x2a,0xed,0x7e,0x2b,0xee,0x7f,0x2c,0xee,0x7f,0x2c,0xee,0x86,0x2e,0x4e,0x2b,0xe,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x1,0x0,0x0,0x96,0x4d,0x19,0xee,0x7a,0x2a,0xed,0x79,0x2a,0xed,0x7c,0x2b,0xed,0x7e,0x2b,0xed,0x7e,0x2b,0xef,0x83,0x2d,0x98,0x55,0x1c,0x3,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x20,0xf,0x5,0x4b,0x27,0xe,0x21,0x11,0x5,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x67,0x34,0x11,0xed,0x7b,0x2a,0xec,0x79,0x29,0xed,0x7b,0x2a,0xed,0x7c,0x2b,0xed,0x7d,0x2b,0xee,0x7f,0x2c,0xbb,0x69,0x24,0x11,0x9,0x3,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x38,0x1c,0x9,0xc9,0x6d,0x2c,0xf1,0x86,0x36,0xd7,0x79,0x2a,0x22,0x12,0x5,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x3b,0x1d,0x9,0xe0,0x74,0x27,0xed,0x7a,0x2a,0xed,0x7c,0x2a,0xed,0x7d,0x2b,0xed,0x7d,0x2b,0xed,0x7d,0x2b,0xdc,0x7a,0x2a,0x1e,0xf,0x5,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xa6,0x56,0x23,0xee,0x83,0x3b,0xed,0x7d,0x2c,0xf0,0x85,0x2e,0x75,0x43,0x17,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x25,0x12,0x5,0xc9,0x68,0x24,0xed,0x7b,0x2a,0xed,0x7d,0x2b,0xed,0x7e,0x2b,0xee,0x7e,0x2c,0xed,0x7d,0x2b,0xe3,0x7d,0x2b,0x3b,0x1f,0xa,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x1c,0xd,0x4,0xd9,0x74,0x35,0xee,0x83,0x3a,0xee,0x7f,0x2b,0xf0,0x86,0x2e,0x83,0x4d,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xa,0x5,0x1,0xa1,0x54,0x1c,0xee,0x7e,0x2c,0xed,0x7e,0x2c,0xed,0x7f,0x2c,0xed,0x80,0x2c,0xed,0x7f,0x2b,0xec,0x81,0x2d,0x60,0x33,0x11,0x1,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x24,0x11,0x5,0xe0,0x7a,0x38,0xee,0x84,0x3a,0xee,0x82,0x2c,0xf0,0x88,0x2f,0x82,0x4d,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x6f,0x39,0x13,0xef,0x82,0x30,0xed,0x82,0x2f,0xee,0x82,0x2e,0xee,0x82,0x2d,0xee,0x81,0x2c,0xf0,0x83,0x2d,0x88,0x49,0x18,0x3,0x2,0x1,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x24,0x11,0x5,0xe0,0x7c,0x3a,0xee,0x86,0x3b,0xee,0x84,0x2d,0xf1,0x8b,0x30,0x82,0x4d,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0x54,0x2b,0xf,0xe9,0x80,0x30,0xee,0x87,0x33,0xef,0x88,0x32,0xef,0x88,0x30,0xee,0x85,0x2f,0xef,0x83,0x2e,0xae,0x5f,0x20,0x4,0x2,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x24,0x11,0x5,0xe0,0x7e,0x3d,0xef,0x8a,0x3d,0xef,0x88,0x2e,0xf1,0x8d,0x31,0x81,0x4d,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0x29,0x15,0x7,0xd2,0x74,0x2d,0xf0,0x8b,0x36,0xf0,0x8d,0x35,0xef,0x8d,0x35,0xef,0x8b,0x33,0xef,0x88,0x30,0xc4,0x6d,0x26,0x18,0xc,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x24,0x11,0x5,0xe1,0x80,0x3f,0xf0,0x8d,0x3f,0xef,0x8a,0x2f,0xf1,0x8f,0x32,0x81,0x4e,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0x9,0x3,0x0,0xb1,0x61,0x26,0xf1,0x8e,0x3a,0xf1,0x90,0x3a,0xf0,0x90,0x38,0xf0,0x90,0x36,0xef,0x8e,0x35,0xd3,0x7a,0x2c,0x22,0x11,0x6,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x24,0x12,0x5,0xe1,0x83,0x42,0xf0,0x90,0x42,0xf0,0x8d,0x30,0xf2,0x92,0x33,0x80,0x4e,0x1b,0x0,0x0,0x0,0x3,0x2,0x0,0x81,0x45,0x1b,0xf1,0x90,0x3e,0xf1,0x94,0x3d,0xf1,0x95,0x3c,0xf0,0x94,0x3b,0xf0,0x92,0x39,0xf0,0x90,0x35,0xd0,0x7b,0x2b,0xc2,0x6e,0x26,0xbe,0x6c,0x25,0x94,0x54,0x1c,0x5b,0x33,0x11,0x1a,0xe,0x4,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x25,0x14,0x6,0xe2,0x86,0x44,0xf1,0x94,0x45,0xf0,0x90,0x31,0xf2,0x94,0x33,0x80,0x4e,0x1b,0x0,0x0,0x0,0x60,0x34,0x14,0xed,0x8c,0x3e,0xf0,0x96,0x42,0xf1,0x97,0x40,0xf1,0x95,0x3f,0xf0,0x91,0x39,0xef,0x8e,0x33,0xef,0x8d,0x31,0xf0,0x8d,0x31,0xef,0x8c,0x30,0xef,0x8c,0x30,0xf0,0x8d,0x31,0xf1,0x8e,0x31,0xe1,0x85,0x2e,0x92,0x55,0x1d,0x25,0x14,0x7,0x1,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe2,0x89,0x46,0xf2,0x97,0x47,0xf1,0x92,0x32,0xf2,0x96,0x34,0x80,0x4e,0x1a,0x32,0x1a,0xa,0xe3,0x87,0x3d,0xf1,0x97,0x45,0xf1,0x98,0x44,0xf1,0x95,0x41,0xf0,0x90,0x39,0xef,0x8d,0x30,0xef,0x8f,0x31,0xf0,0x90,0x32,0xf0,0x92,0x33,0xf1,0x93,0x33,0xf1,0x94,0x34,0xf1,0x94,0x34,0xf0,0x93,0x34,0xf0,0x91,0x32,0xf1,0x91,0x33,0xe2,0x8a,0x30,0x6b,0x3f,0x15,0x1,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe3,0x8b,0x49,0xf2,0x9a,0x49,0xf1,0x93,0x32,0xf2,0x98,0x35,0x8f,0x57,0x1d,0xcf,0x7c,0x38,0xf2,0x99,0x48,0xf1,0x98,0x47,0xf1,0x96,0x44,0xf0,0x90,0x39,0xef,0x8d,0x31,0xf0,0x90,0x31,0xf0,0x92,0x33,0xf1,0x94,0x33,0xf1,0x96,0x35,0xf1,0x98,0x35,0xf1,0x9a,0x36,0xf1,0x9c,0x37,0xf2,0x9d,0x37,0xf2,0x9c,0x37,0xf2,0x99,0x36,0xf0,0x94,0x34,0xf3,0x97,0x35,0x9f,0x60,0x21,0x13,0xb,0x3,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe3,0x8d,0x4b,0xf2,0x9b,0x4c,0xf1,0x93,0x32,0xf1,0x97,0x35,0xea,0x98,0x43,0xf2,0x9d,0x4d,0xf1,0x9a,0x4b,0xf1,0x99,0x49,0xf0,0x93,0x3d,0xf0,0x8d,0x30,0xf0,0x90,0x32,0xf0,0x92,0x32,0xf0,0x94,0x34,0xf1,0x96,0x34,0xf1,0x98,0x36,0xf1,0x9a,0x36,0xf2,0x9c,0x38,0xf2,0x9f,0x38,0xf2,0xa2,0x39,0xf3,0xa2,0x39,0xf3,0xa2,0x39,0xf2,0x9f,0x38,0xf1,0x99,0x35,0xf2,0x97,0x35,0xba,0x74,0x29,0x13,0xb,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe4,0x8e,0x4d,0xf2,0x9d,0x4e,0xf1,0x93,0x32,0xf2,0x9d,0x3f,0xf3,0xa4,0x54,0xf2,0x9d,0x50,0xf1,0x9b,0x4d,0xf2,0x98,0x46,0xef,0x8d,0x31,0xf0,0x8f,0x31,0xf0,0x91,0x32,0xf0,0x93,0x32,0xf1,0x94,0x32,0xf1,0x95,0x32,0xf1,0x98,0x34,0xf1,0x9b,0x36,0xf2,0x9e,0x38,0xf2,0xa1,0x39,0xf2,0xa4,0x3a,0xf3,0xa6,0x3b,0xf4,0xa8,0x3c,0xf3,0xa7,0x3c,0xf3,0xa4,0x3a,0xf2,0x9c,0x37,0xf2,0x99,0x36,0xa9,0x69,0x25,0x2,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe4,0x90,0x50,0xf2,0x9e,0x51,0xf1,0x95,0x35,0xf4,0xa6,0x54,0xf3,0xa2,0x55,0xf2,0x9e,0x51,0xf2,0x9c,0x4e,0xf0,0x8f,0x35,0xf0,0x8e,0x31,0xf0,0x90,0x32,0xf3,0xa5,0x56,0xf7,0xc4,0x8e,0xfa,0xd8,0xb6,0xfb,0xdf,0xc2,0xfa,0xd8,0xb2,0xf7,0xc4,0x89,0xf4,0xae,0x59,0xf2,0xa1,0x38,0xf3,0xa5,0x3b,0xf4,0xa8,0x3c,0xf4,0xab,0x3d,0xf4,0xac,0x3e,0xf4,0xab,0x3d,0xf3,0xa7,0x3b,0xf2,0x9e,0x38,0xf4,0x9e,0x38,0x6f,0x45,0x17,0x1,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x19,0xc,0x5,0x63,0x36,0x18,0x3f,0x20,0x9,0x2,0x1,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x26,0x14,0x6,0xe4,0x91,0x52,0xf3,0xa2,0x55,0xf2,0x9d,0x43,0xf4,0xa7,0x5b,0xf3,0xa2,0x57,0xf3,0xa0,0x55,0xf1,0x97,0x43,0xf0,0x8d,0x30,0xf2,0x9d,0x4c,0xfa,0xda,0xbc,0xfe,0xfb,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfb,0xf6,0xfa,0xdc,0xb5,0xf4,0xae,0x4e,0xf4,0xa9,0x3c,0xf4,0xac,0x3d,0xf4,0xae,0x3f,0xf4,0xaf,0x3f,0xf4,0xad,0x3f,0xf3,0xa8,0x3d,0xf2,0x9d,0x38,0xe2,0x94,0x34,0x23,0x14,0x6,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x11,0x8,0x3,0x9e,0x62,0x39,0xf2,0x91,0x4e,0xe7,0x79,0x29,0x48,0x25,0xc,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0x27,0x13,0x6,0xe5,0x93,0x54,0xf3,0xa7,0x59,0xf4,0xa6,0x56,0xf4,0xa7,0x5d,0xf3,0xa4,0x59,0xf3,0xa2,0x57,0xf1,0x90,0x36,0xf4,0xa7,0x5d,0xfe,0xf4,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xf2,0xe3,0xf6,0xb8,0x5f,0xf4,0xac,0x3e,0xf4,0xaf,0x3f,0xf4,0xb1,0x40,0xf4,0xb2,0x40,0xf5,0xaf,0x3f,0xf3,0xa6,0x3c,0xf3,0x9f,0x38,0x90,0x5d,0x21,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x3d,0x1f,0xf,0xed,0x9c,0x6a,0xef,0x8b,0x4a,0xec,0x78,0x29,0xe4,0x79,0x2a,0x29,0x15,0x7,0x0,0x0,0x0,0xff,0x0,0xff,0x28,0x14,0x6,0xe6,0x97,0x57,0xf5,0xad,0x63,0xf5,0xac,0x62,0xf4,0xa8,0x5f,0xf4,0xa6,0x5c,0xf3,0xa0,0x53,0xf4,0xa9,0x64,0xfe,0xf8,0xf4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xff,0xf2,0xf7,0xfa,0xed,0xf4,0xf8,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf7,0xed,0xf5,0xb5,0x53,0xf5,0xb0,0x3f,0xf5,0xb3,0x41,0xf5,0xb4,0x42,0xf5,0xb3,0x41,0xf4,0xad,0x3f,0xf3,0xa1,0x39,0xe4,0x98,0x37,0x1d,0x11,0x5,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x43,0x23,0x10,0xf2,0xa1,0x70,0xf1,0x99,0x61,0xec,0x78,0x2a,0xed,0x7b,0x2a,0xc4,0x69,0x23,0x15,0xa,0x3,0x0,0x0,0x0,0x1d,0xf,0x5,0xe7,0x9b,0x5b,0xf5,0xb1,0x68,0xf5,0xad,0x65,0xf4,0xaa,0x62,0xf4,0xa8,0x5f,0xf3,0xa4,0x59,0xfd,0xec,0xde,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xfd,0xfe,0xc3,0xda,0xe9,0x5c,0x9a,0xc5,0x2a,0x7b,0xb4,0x17,0x6f,0xae,0x36,0x81,0xb8,0x91,0xbb,0xd9,0xf0,0xf6,0xfa,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe7,0xc7,0xf5,0xb2,0x43,0xf6,0xb3,0x41,0xf5,0xb5,0x43,0xf5,0xb6,0x43,0xf5,0xb3,0x42,0xf4,0xa8,0x3c,0xf4,0xa2,0x3a,0x66,0x41,0x17,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x22,0x10,0x7,0xd6,0x88,0x5b,0xf2,0xa5,0x76,0xee,0x84,0x3f,0xed,0x7a,0x2a,0xee,0x80,0x2c,0xa5,0x59,0x1e,0x7,0x3,0x1,0x19,0xd,0x4,0xe7,0x9e,0x5e,0xf6,0xb2,0x6b,0xf5,0xae,0x67,0xf5,0xac,0x65,0xf4,0xa9,0x61,0xf8,0xcc,0xa1,0xff,0xff,0xfe,0xff,0xff,0xff,0xfd,0xfe,0xfe,0x97,0xbf,0xdb,0x33,0x83,0xbb,0x24,0x7e,0xb9,0x3,0x6a,0xae,0x0,0x66,0xab,0x0,0x64,0xa9,0x1,0x63,0xa9,0x3c,0x87,0xbd,0xee,0xf5,0xf9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xf8,0xc7,0x76,0xf6,0xb4,0x41,0xf5,0xb7,0x43,0xf6,0xb8,0x44,0xf6,0xb6,0x43,0xf5,0xae,0x3f,0xf3,0xa2,0x3a,0xac,0x71,0x29,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x52,0x2c,0x16,0xf0,0xa1,0x71,0xf2,0xa2,0x6f,0xed,0x7e,0x32,0xed,0x7e,0x2b,0xef,0x82,0x2d,0x8a,0x49,0x18,0x1b,0xe,0x4,0xe7,0xa2,0x61,0xf6,0xb3,0x6e,0xf6,0xb0,0x6a,0xf5,0xae,0x67,0xf5,0xab,0x64,0xfe,0xf4,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xb4,0xd1,0xe5,0x3e,0x8d,0xc3,0x37,0x8e,0xc5,0x16,0x7a,0xb9,0x0,0x6b,0xaf,0x0,0x68,0xac,0x0,0x65,0xaa,0x0,0x65,0xab,0x0,0x66,0xac,0x4d,0x93,0xc4,0xf8,0xfb,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe7,0xc5,0xf6,0xb3,0x40,0xf6,0xb7,0x43,0xf6,0xb9,0x44,0xf6,0xb8,0x45,0xf5,0xb2,0x41,0xf3,0xa5,0x3b,0xe2,0x98,0x37,0x3,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x86,0x4e,0x2e,0xf3,0xa6,0x77,0xf1,0x9e,0x66,0xed,0x7e,0x2d,0xee,0x82,0x2c,0xf0,0x85,0x2d,0x7e,0x47,0x17,0xe8,0xa6,0x64,0xf6,0xb5,0x70,0xf6,0xb2,0x6d,0xf5,0xb0,0x6a,0xf7,0xbb,0x80,0xff,0xff,0xff,0xff,0xff,0xff,0xf9,0xfb,0xfd,0x5b,0x9c,0xca,0x42,0x96,0xcb,0x3c,0x93,0xc9,0x9,0x73,0xb6,0x0,0x6b,0xb0,0x0,0x69,0xad,0x0,0x66,0xab,0x0,0x66,0xab,0x0,0x67,0xad,0x4,0x6a,0xaf,0xbb,0xd7,0xe9,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf8,0xee,0xf6,0xb9,0x4f,0xf6,0xb7,0x44,0xf6,0xba,0x45,0xf6,0xba,0x45,0xf5,0xb5,0x43,0xf4,0xa8,0x3d,0xf5,0xa7,0x3d,0x1b,0xf,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x11,0x8,0x3,0xb0,0x6d,0x45,0xf4,0xaa,0x7b,0xf1,0x9a,0x5b,0xee,0x82,0x2d,0xef,0x86,0x2e,0xee,0x91,0x36,0xf5,0xb5,0x70,0xf6,0xb7,0x73,0xf6,0xb4,0x70,0xf5,0xb1,0x6c,0xf9,0xcc,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xd1,0xe2,0xef,0x4b,0x97,0xca,0x47,0x9a,0xce,0x3f,0x95,0xcb,0x3,0x71,0xb5,0x0,0x6c,0xb0,0x0,0x69,0xae,0x0,0x67,0xac,0x0,0x66,0xac,0x0,0x67,0xad,0x0,0x69,0xaf,0x66,0xa5,0xcf,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfa,0xf8,0xc3,0x67,0xf6,0xb8,0x44,0xf6,0xba,0x45,0xf6,0xbb,0x46,0xf6,0xb7,0x44,0xf4,0xab,0x3e,0xf8,0xab,0x3f,0x2a,0x19,0x8,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x2b,0x15,0x9,0xd4,0x8a,0x5c,0xf4,0xac,0x7c,0xf1,0x98,0x54,0xee,0x85,0x2e,0xf1,0x93,0x38,0xf6,0xba,0x75,0xf6,0xb9,0x75,0xf6,0xb6,0x72,0xf6,0xb3,0x6f,0xfa,0xd5,0xb1,0xff,0xff,0xff,0xff,0xff,0xff,0xb0,0xcf,0xe5,0x51,0x9e,0xcf,0x4b,0x9d,0xd0,0x43,0x97,0xcc,0x3,0x71,0xb5,0x0,0x6d,0xb1,0x0,0x6a,0xae,0x0,0x67,0xac,0x0,0x67,0xad,0x0,0x68,0xae,0x0,0x6a,0xb0,0x3b,0x8c,0xc2,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf9,0xc9,0x77,0xf6,0xb8,0x44,0xf6,0xba,0x45,0xf6,0xbc,0x46,0xf6,0xb8,0x44,0xf4,0xad,0x3f,0xf8,0xac,0x3f,0x2a,0x1a,0x8,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x47,0x26,0x12,0xee,0xa3,0x72,0xf4,0xae,0x7b,0xf1,0x97,0x4e,0xf1,0x92,0x38,0xf6,0xbb,0x78,0xf6,0xbb,0x78,0xf6,0xb7,0x75,0xf6,0xb5,0x71,0xfa,0xd6,0xb2,0xff,0xff,0xff,0xff,0xff,0xff,0xad,0xcd,0xe4,0x54,0xa0,0xd1,0x4e,0xa0,0xd1,0x48,0x9b,0xce,0xb,0x76,0xb8,0x0,0x6d,0xb2,0x0,0x6a,0xaf,0x0,0x68,0xad,0x0,0x68,0xad,0x0,0x69,0xae,0x0,0x6b,0xb1,0x36,0x89,0xc1,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xf9,0xc9,0x76,0xf6,0xb9,0x44,0xf6,0xbb,0x46,0xf6,0xbc,0x47,0xf6,0xb9,0x44,0xf4,0xad,0x3f,0xf8,0xad,0x40,0x2a,0x1a,0x8,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x70,0x42,0x26,0xf4,0xad,0x7b,0xf5,0xb1,0x7d,0xf3,0x9f,0x50,0xf7,0xbc,0x7b,0xf7,0xbc,0x7b,0xf6,0xb9,0x78,0xf6,0xb7,0x74,0xf9,0xd0,0xa6,0xff,0xff,0xff,0xff,0xff,0xff,0xc3,0xda,0xeb,0x56,0xa0,0xd0,0x51,0xa1,0xd2,0x4a,0x9c,0xcf,0x20,0x82,0xbf,0x0,0x6e,0xb2,0x0,0x6b,0xb0,0x0,0x68,0xae,0x0,0x68,0xae,0x0,0x69,0xaf,0x0,0x6b,0xb1,0x50,0x98,0xc9,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xf9,0xf8,0xc3,0x66,0xf6,0xb9,0x45,0xf7,0xbb,0x46,0xf6,0xbc,0x47,0xf6,0xb8,0x45,0xf4,0xad,0x3f,0xf8,0xac,0x3f,0x2a,0x19,0x7,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xc,0x5,0x0,0xa5,0x67,0x40,0xf5,0xb1,0x7f,0xf5,0xb7,0x7e,0xf7,0xbf,0x80,0xf7,0xbe,0x7d,0xf7,0xbb,0x7b,0xf6,0xb9,0x78,0xf8,0xc2,0x8b,0xff,0xff,0xff,0xff,0xff,0xff,0xee,0xf5,0xf9,0x5b,0xa0,0xce,0x53,0xa2,0xd2,0x4c,0x9e,0xd0,0x3c,0x93,0xc8,0x6,0x71,0xb4,0x0,0x6c,0xb0,0x0,0x69,0xae,0x0,0x69,0xae,0x0,0x6a,0xaf,0x0,0x6b,0xb1,0x9b,0xc5,0xe0,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf7,0xec,0xf6,0xba,0x4e,0xf6,0xb9,0x45,0xf7,0xbb,0x46,0xf6,0xbc,0x47,0xf5,0xb7,0x44,0xf4,0xab,0x3e,0xf5,0xa8,0x3e,0x18,0xd,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x1f,0x10,0x7,0xc9,0x84,0x56,0xf5,0xb5,0x81,0xf7,0xbf,0x82,0xf8,0xc0,0x80,0xf7,0xbd,0x7d,0xf7,0xba,0x7a,0xf6,0xb8,0x77,0xfe,0xf5,0xec,0xff,0xff,0xff,0xff,0xff,0xff,0x9a,0xc2,0xdf,0x55,0x9f,0xd0,0x4e,0x9f,0xd0,0x47,0x99,0xcc,0x2a,0x87,0xc1,0x3,0x6d,0xb1,0x0,0x69,0xaf,0x0,0x6a,0xaf,0x0,0x6a,0xb0,0x27,0x80,0xbc,0xec,0xf4,0xf9,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe5,0xbf,0xf6,0xb6,0x42,0xf6,0xba,0x46,0xf7,0xbb,0x46,0xf7,0xbb,0x47,0xf5,0xb5,0x43,0xf3,0xa8,0x3d,0xdd,0x97,0x37,0x2,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x32,0x1a,0xb,0xe4,0x9d,0x6a,0xf7,0xbd,0x84,0xf8,0xc1,0x83,0xf8,0xbe,0x80,0xf7,0xbd,0x7d,0xf7,0xba,0x79,0xfa,0xd9,0xb6,0xff,0xff,0xff,0xff,0xff,0xff,0xf0,0xf6,0xfa,0x74,0xac,0xd4,0x4f,0x9b,0xcd,0x48,0x99,0xcc,0x41,0x94,0xc8,0x2c,0x85,0xbe,0xb,0x70,0xb3,0x1,0x6a,0xb0,0xb,0x6e,0xb2,0xbf,0xd9,0xeb,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfd,0xf8,0xc8,0x74,0xf6,0xb7,0x44,0xf6,0xba,0x46,0xf7,0xbb,0x46,0xf7,0xb9,0x46,0xf6,0xb2,0x42,0xf4,0xa7,0x3d,0xa6,0x70,0x29,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x4f,0x2e,0x18,0xef,0xaf,0x78,0xf8,0xc1,0x85,0xf8,0xc0,0x82,0xf7,0xbe,0x7f,0xf7,0xbc,0x7d,0xf7,0xbe,0x81,0xfe,0xf3,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0xf2,0xf7,0xfa,0x91,0xbd,0xdb,0x4f,0x97,0xc8,0x40,0x8e,0xc3,0x37,0x8a,0xc0,0x34,0x88,0xbf,0x57,0x9c,0xca,0xcc,0xe1,0xef,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0xe4,0xbf,0xf5,0xb6,0x45,0xf6,0xb8,0x45,0xf6,0xba,0x46,0xf7,0xba,0x46,0xf6,0xb7,0x45,0xf5,0xad,0x3f,0xf4,0xa9,0x40,0x5c,0x3d,0x18,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x85,0x55,0x31,0xf7,0xbd,0x84,0xf8,0xc2,0x85,0xf8,0xc0,0x82,0xf7,0xbe,0x80,0xf7,0xbc,0x7d,0xf9,0xcb,0x99,0xfe,0xf9,0xf4,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xfe,0xfe,0xe5,0xef,0xf6,0xc1,0xda,0xeb,0xba,0xd5,0xe9,0xd8,0xe8,0xf2,0xf9,0xfb,0xfd,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xf3,0xe4,0xf6,0xb9,0x51,0xf5,0xb5,0x43,0xf6,0xb8,0x45,0xf6,0xb9,0x46,0xf6,0xb8,0x46,0xf6,0xb3,0x43,0xf4,0xa7,0x3e,0xdf,0x9d,0x43,0x17,0xd,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x14,0xa,0x4,0xb2,0x7b,0x4b,0xf8,0xc2,0x88,0xf8,0xc1,0x85,0xf7,0xbf,0x82,0xf7,0xbe,0x80,0xf7,0xbd,0x7d,0xf9,0xca,0x97,0xfe,0xf9,0xf4,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfd,0xf2,0xe1,0xf7,0xbc,0x5d,0xf5,0xb3,0x42,0xf5,0xb6,0x44,0xf5,0xb7,0x45,0xf6,0xb8,0x45,0xf6,0xb5,0x44,0xf5,0xad,0x40,0xf6,0xae,0x4c,0x88,0x5d,0x27,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x1d,0x10,0x6,0xdb,0xa0,0x68,0xf8,0xc3,0x88,0xf7,0xc1,0x85,0xf7,0xc0,0x82,0xf7,0xbf,0x80,0xf7,0xbe,0x7e,0xf8,0xc4,0x88,0xfc,0xe6,0xcc,0xfe,0xfb,0xf7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfa,0xf3,0xfa,0xda,0xa9,0xf5,0xb3,0x4a,0xf5,0xb2,0x42,0xf5,0xb3,0x43,0xf5,0xb6,0x44,0xf5,0xb7,0x45,0xf5,0xb5,0x44,0xf5,0xb0,0x42,0xf5,0xad,0x4d,0xdd,0x9e,0x4a,0x19,0xf,0x5,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x50,0x33,0x19,0xec,0xb4,0x7a,0xf8,0xc2,0x87,0xf7,0xc1,0x85,0xf7,0xc1,0x83,0xf7,0xc0,0x80,0xf7,0xc0,0x7f,0xf7,0xc0,0x7c,0xf7,0xc2,0x7e,0xf8,0xcc,0x92,0xfa,0xda,0xb0,0xfb,0xdf,0xb9,0xfa,0xd9,0xad,0xf7,0xc8,0x84,0xf5,0xb4,0x54,0xf4,0xad,0x3f,0xf4,0xaf,0x41,0xf5,0xb2,0x42,0xf5,0xb4,0x43,0xf5,0xb5,0x44,0xf5,0xb4,0x44,0xf5,0xb2,0x46,0xf5,0xb2,0x54,0xf5,0xb4,0x5a,0x5e,0x3e,0x1a,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x71,0x4b,0x29,0xf8,0xc0,0x86,0xf7,0xc3,0x87,0xf7,0xc2,0x85,0xf7,0xc1,0x83,0xf7,0xc2,0x82,0xf7,0xc2,0x7f,0xf7,0xc2,0x7e,0xf6,0xc0,0x76,0xf4,0xb4,0x59,0xf3,0xa8,0x3e,0xf3,0xa7,0x39,0xf3,0xa9,0x3d,0xf4,0xab,0x3e,0xf4,0xad,0x40,0xf4,0xb0,0x41,0xf4,0xb2,0x42,0xf5,0xb2,0x42,0xf5,0xb3,0x45,0xf6,0xb7,0x54,0xf6,0xb7,0x60,0xf6,0xb5,0x5f,0x9d,0x6b,0x31,0x2,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x8b,0x5f,0x36,0xf9,0xc1,0x87,0xf7,0xc3,0x88,0xf8,0xc3,0x86,0xf7,0xc3,0x84,0xf8,0xc3,0x81,0xf7,0xc4,0x80,0xf7,0xc4,0x7e,0xf7,0xc4,0x7d,0xf7,0xc3,0x7a,0xf6,0xbd,0x6c,0xf5,0xb7,0x5c,0xf5,0xb5,0x54,0xf5,0xb4,0x50,0xf5,0xb6,0x52,0xf6,0xb9,0x58,0xf6,0xbd,0x62,0xf7,0xbf,0x6a,0xf6,0xba,0x66,0xf6,0xb6,0x63,0xab,0x78,0x39,0xa,0x6,0x2,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x83,0x58,0x32,0xf0,0xb9,0x7f,0xf7,0xc3,0x88,0xf7,0xc3,0x86,0xf8,0xc4,0x84,0xf7,0xc5,0x82,0xf7,0xc5,0x80,0xf7,0xc5,0x7f,0xf8,0xc5,0x7d,0xf7,0xc4,0x7b,0xf7,0xc4,0x79,0xf7,0xc4,0x78,0xf7,0xc3,0x76,0xf7,0xc3,0x74,0xf7,0xc2,0x71,0xf6,0xbe,0x6d,0xf6,0xba,0x6a,0xf4,0xb6,0x65,0x8a,0x5e,0x2c,0xc,0x7,0x3,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x4f,0x33,0x1a,0xd2,0x99,0x60,0xf8,0xc4,0x89,0xf8,0xc3,0x86,0xf8,0xc4,0x84,0xf7,0xc5,0x82,0xf7,0xc5,0x80,0xf7,0xc5,0x7f,0xf7,0xc4,0x7e,0xf7,0xc4,0x7b,0xf7,0xc3,0x79,0xf7,0xc2,0x77,0xf6,0xc0,0x74,0xf6,0xbd,0x71,0xf6,0xbb,0x6e,0xe1,0xa4,0x59,0x5c,0x3d,0x1b,0x1,0x1,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xe,0x6,0x0,0x72,0x4b,0x28,0xd0,0x9a,0x62,0xf7,0xbf,0x80,0xf8,0xc4,0x85,0xf7,0xc3,0x82,0xf7,0xc3,0x80,0xf7,0xc3,0x7e,0xf7,0xc1,0x7c,0xf6,0xc0,0x7a,0xf7,0xbf,0x78,0xf8,0xbc,0x72,0xde,0xa2,0x5d,0x80,0x57,0x2b,0x13,0xb,0x4,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x19,0xe,0x5,0x44,0x2c,0x15,0x81,0x59,0x32,0xb2,0x80,0x4c,0xcb,0x95,0x5b,0xd2,0x9c,0x5f,0xcd,0x97,0x5a,0xb9,0x86,0x4d,0x8b,0x61,0x34,0x4a,0x30,0x17,0x15,0xc,0x5,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0x0,0x0,0x0,0x1,0x0,0x0,0x3,0x0,0x0,0x1,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,0xff,0x0,0xff,
};


GLXContext GHOST_WindowX11::s_firstContext = NULL;

GHOST_WindowX11::
GHOST_WindowX11(
	GHOST_SystemX11 *system,
	Display * display,
	const STR_String& title, 
	GHOST_TInt32 left,
	GHOST_TInt32 top,
	GHOST_TUns32 width,	
	GHOST_TUns32 height,
	GHOST_TWindowState state,
	const GHOST_TEmbedderWindowID parentWindow,
	GHOST_TDrawingContextType type,
	const bool stereoVisual,
	const GHOST_TUns16 numOfAASamples
) :
	GHOST_Window(title,left,top,width,height,state,type,stereoVisual,numOfAASamples),
	m_context(NULL),
	m_display(display),
	m_normal_state(GHOST_kWindowStateNormal),
	m_system (system),
	m_valid_setup (false),
	m_invalid_window(false),
	m_empty_cursor(None),
	m_custom_cursor(None)
{
	
	// Set up the minimum atrributes that we require and see if
	// X can find us a visual matching those requirements.

	int attributes[40], i, samples;
	Atom atoms[2];
	int natom;
	int glxVersionMajor, glxVersionMinor; // As in GLX major.minor
	
	/* initialize incase X11 fails to load */
	memset(&m_xtablet, 0, sizeof(m_xtablet));
	m_visual= NULL;

	if (!glXQueryVersion(m_display, &glxVersionMajor, &glxVersionMinor)) {
		printf("%s:%d: X11 glXQueryVersion() failed, verify working openGL system!\n", __FILE__, __LINE__);
		
		/* exit if this is the first window */
		if(s_firstContext==NULL) {
			printf("initial window could not find the GLX extension, exit!\n");
			exit(1);
		}

		return;
	}

	/* Find the display with highest samples, starting at level requested */
	for (samples = m_numOfAASamples; samples >= 0; samples--) {
		i = 0; /* Reusing attributes array, so reset counter */

		if(m_stereoVisual)
			attributes[i++] = GLX_STEREO;

		attributes[i++] = GLX_RGBA;
		attributes[i++] = GLX_DOUBLEBUFFER;
		attributes[i++] = GLX_RED_SIZE;   attributes[i++] = 1;
		attributes[i++] = GLX_BLUE_SIZE;  attributes[i++] = 1;
		attributes[i++] = GLX_GREEN_SIZE; attributes[i++] = 1;
		attributes[i++] = GLX_DEPTH_SIZE; attributes[i++] = 1;
		/* GLX >= 1.4 required for multi-sample */
		if(samples && (glxVersionMajor >= 1) && (glxVersionMinor >= 4)) {
			attributes[i++] = GLX_SAMPLE_BUFFERS; attributes[i++] = 1;
			attributes[i++] = GLX_SAMPLES; attributes[i++] = samples;
		}
		attributes[i] = None;

		m_visual = glXChooseVisual(m_display, DefaultScreen(m_display), attributes);

		/* Any sample level or even zero, which means oversampling disabled, is good
		   but we need a valid visual to continue */
		if (m_visual == NULL) {
			if (samples == 0) {
				/* All options exhausted, cannot continue */
				printf("%s:%d: X11 glXChooseVisual() failed, verify working openGL system!\n", __FILE__, __LINE__);
				
				if(s_firstContext==NULL) {
					printf("initial window could not find the GLX extension, exit!\n");
					exit(1);
				}
				
				return;
			}
		} else {
			if (m_numOfAASamples && (m_numOfAASamples > samples)) {
				printf("%s:%d: oversampling requested %i but using %i samples\n", __FILE__, __LINE__, m_numOfAASamples, samples);
			}
			break;
		}
	}

	// Create a bunch of attributes needed to create an X window.


	// First create a colormap for the window and visual. 
	// This seems pretty much a legacy feature as we are in rgba mode anyway.

	XSetWindowAttributes xattributes;
	memset(&xattributes, 0, sizeof(xattributes));

	xattributes.colormap= XCreateColormap(
		m_display, 
		RootWindow(m_display, m_visual->screen),
		m_visual->visual,
		AllocNone
	);

	xattributes.border_pixel= 0;

	// Specify which events we are interested in hearing.	

	xattributes.event_mask= 
		ExposureMask | StructureNotifyMask | 
		KeyPressMask | KeyReleaseMask |
		EnterWindowMask | LeaveWindowMask |
		ButtonPressMask | ButtonReleaseMask |
		PointerMotionMask | FocusChangeMask | PropertyChangeMask;

	// create the window!

	;
	if (parentWindow == 0) {
		m_window = 
			XCreateWindow(
				m_display, 
				RootWindow(m_display, m_visual->screen), 
				left,
				top,
				width,
				height,
				0, // no border.
				m_visual->depth,
				InputOutput, 
				m_visual->visual,
				CWBorderPixel|CWColormap|CWEventMask, 
				&xattributes
			);
	} else {

		Window root_return;
		int x_return,y_return;
		unsigned int w_return,h_return,border_w_return,depth_return;
		
		XGetGeometry(m_display, parentWindow, &root_return, &x_return, &y_return,
			&w_return, &h_return, &border_w_return, &depth_return );

		left = 0;
		top = 0;
		width = w_return;
		height = h_return;


		m_window = XCreateWindow(
				m_display, 
				parentWindow,  // reparent against embedder 
				left,
				top,
				width,
				height,
				0, // no border.
				m_visual->depth,
				InputOutput, 
				m_visual->visual,
				CWBorderPixel|CWColormap|CWEventMask, 
				&xattributes
			);

		XSelectInput(m_display , parentWindow, SubstructureNotifyMask);
		
	}	
	
	/*
	 * One of the problem with WM-spec is that can't set a property
	 * to a window that isn't mapped. That is why we can't "just
	 * call setState" here.
	 *
	 * To fix this, we first need know that the window is really
	 * map waiting for the MapNotify event.
	 *
	 * So, m_post_init indicate that we need wait for the MapNotify
	 * event and then set the Window state to the m_post_state.
	 */
	if ((state != GHOST_kWindowStateNormal) && (state != GHOST_kWindowStateMinimized)) {
		m_post_init = True;
		m_post_state = state;
	}
	else {
		m_post_init = False;
		m_post_state = GHOST_kWindowStateNormal;
	}
	
	// Create some hints for the window manager on how
	// we want this window treated.

	XSizeHints * xsizehints = XAllocSizeHints();
	xsizehints->flags = PPosition | PSize | PMinSize | PMaxSize;
	xsizehints->x = left;
	xsizehints->y = top;
	xsizehints->width = width;
	xsizehints->height = height;
	xsizehints->min_width= 320;  	// size hints, could be made apart of the ghost api
	xsizehints->min_height= 240;	// limits are also arbitrary, but should not allow 1x1 window
	xsizehints->max_width= 65535;
	xsizehints->max_height= 65535;
	XSetWMNormalHints(m_display, m_window, xsizehints);
	XFree(xsizehints);

	XClassHint * xclasshint = XAllocClassHint();
	int len = title.Length() +1 ;
	char *wmclass = (char *)malloc(sizeof(char) * len);
	strncpy(wmclass, (const char*)title, sizeof(char) * len);
	xclasshint->res_name = wmclass;
	xclasshint->res_class = wmclass;
	XSetClassHint(m_display, m_window, xclasshint);
	free(wmclass);
	XFree(xclasshint);

	/* The basic for a good ICCCM "work" */
	if (m_system->m_wm_protocols) {
		natom= 0;

		if (m_system->m_delete_window_atom) {
			atoms[natom]= m_system->m_delete_window_atom;
			natom++;
		}

		if (m_system->m_wm_take_focus) {
			atoms[natom]= m_system->m_wm_take_focus;
			natom++;
		}

		if (natom) {
			/* printf("Register atoms: %d\n", natom); */
			XSetWMProtocols(m_display, m_window, atoms, natom);
		}
	}

	// Set the window icon
	XWMHints *xwmhints = XAllocWMHints();
	XImage *x_image, *mask_image;
	Pixmap icon_pixmap, mask_pixmap;
	icon_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 24);
	mask_pixmap = XCreatePixmap(display, m_window, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 1);
	GC gc_icon = XCreateGC(display, icon_pixmap, 0, NULL);
	GC gc_mask = XCreateGC(display, mask_pixmap, 0, NULL);
	
	x_image = XCreateImage( display, m_visual->visual, 24, ZPixmap, 0, NULL, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 32, 0 );
	mask_image = XCreateImage( display, m_visual->visual, 1, ZPixmap, 0, NULL,  BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT, 8, 0);
	
	x_image->data = (char *)malloc(x_image->bytes_per_line * BLENDER_ICON_HEIGHT);
	mask_image->data = (char *)malloc( mask_image->bytes_per_line * BLENDER_ICON_HEIGHT);
	
	/* copy the BLENDER_ICON_48x48x24 into the XImage */
	unsigned char *col = BLENDER_ICON_48x48x24;
	int px, py;
	for (px=0; px<BLENDER_ICON_WIDTH; px++) {
		for (py=0; py<BLENDER_ICON_HEIGHT; py++, col+=3) {
			/* mask out pink */
			if (col[0]==255 && col[1] == 0 && col[2]== 255) {
				XPutPixel(mask_image, px, py, 0 );
			} else {
				XPutPixel(x_image, px, py, (col[0]<<16)+(col[1]<<8)+col[2] );
				XPutPixel(mask_image, px, py, 1 );
			}
		}
	}
	
	XPutImage(display, icon_pixmap, gc_icon, x_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
	XPutImage(display, mask_pixmap, gc_mask, mask_image, 0, 0, 0, 0, BLENDER_ICON_WIDTH, BLENDER_ICON_HEIGHT);
	
	// Now the pixmap is ok to assign to the window as a hint
	xwmhints->icon_pixmap = icon_pixmap;
	xwmhints->icon_mask = mask_pixmap;
	XFreeGC (display, gc_icon);
	XFreeGC (display, gc_mask);
	XDestroyImage( x_image ); /* frees x_image->data too */
	XDestroyImage( mask_image );
	
	xwmhints->initial_state = NormalState;
	xwmhints->input= True;
	xwmhints->flags= InputHint|IconPixmapHint|IconMaskHint|StateHint;
	XSetWMHints(display, m_window, xwmhints );
	XFree(xwmhints);
	// done setting the icon

	setTitle(title);

#ifdef WITH_X11_XINPUT
	initXInputDevices();
#endif

	// now set up the rendering context.
	if (installDrawingContext(type) == GHOST_kSuccess) {
		m_valid_setup = true;
		GHOST_PRINT("Created window\n");
	}

	XMapWindow(m_display, m_window);
	GHOST_PRINT("Mapped window\n");

	XFlush(m_display);
}

#ifdef WITH_X11_XINPUT
/* 
	Dummy function to get around IO Handler exiting if device invalid
	Basically it will not crash blender now if you have a X device that 
	is configured but not plugged in.

*/
static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) {
	fprintf(stderr, "Ignoring Xlib error: error code %d request code %d\n",
		theEvent->error_code, theEvent->request_code) ;

	/* No exit! - but keep lint happy */
	return 0 ;
}

/* These C functions are copied from Wine 1.1.13's wintab.c */
#define BOOL int
#define TRUE 1
#define FALSE 0

static bool match_token(const char *haystack, const char *needle)
{
	const char *p, *q;
	for (p = haystack; *p; )
	{
		while (*p && isspace(*p))
			p++;
		if (! *p)
			break;

		for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
			p++;
		if (! *q && (isspace(*p) || !*p))
			return TRUE;

		while (*p && ! isspace(*p))
			p++;
	}
	return FALSE;
}


/*	Determining if an X device is a Tablet style device is an imperfect science.
**  We rely on common conventions around device names as well as the type reported
**  by Wacom tablets.  This code will likely need to be expanded for alternate tablet types
**
**	Wintab refers to any device that interacts with the tablet as a cursor,
**  (stylus, eraser, tablet mouse, airbrush, etc)
**  this is not to be confused with wacom x11 configuration "cursor" device.
**  Wacoms x11 config "cursor" refers to its device slot (which we mirror with
**  our gSysCursors) for puck like devices (tablet mice essentially).
*/
#if 0 // unused
static BOOL is_tablet_cursor(const char *name, const char *type)
{
	int i;
	static const char *tablet_cursor_whitelist[] = {
		"wacom",
		"wizardpen",
		"acecad",
		"tablet",
		"cursor",
		"stylus",
		"eraser",
		"pad",
		NULL
	};

	for (i=0; tablet_cursor_whitelist[i] != NULL; i++) {
		if (name && match_token(name, tablet_cursor_whitelist[i]))
			return TRUE;
		if (type && match_token(type, tablet_cursor_whitelist[i]))
			return TRUE;
	}
	return FALSE;
}
#endif
static BOOL is_stylus(const char *name, const char *type)
{
	int i;
	static const char* tablet_stylus_whitelist[] = {
		"stylus",
		"wizardpen",
		"acecad",
		NULL
	};

	for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
		if (name && match_token(name, tablet_stylus_whitelist[i]))
			return TRUE;
		if (type && match_token(type, tablet_stylus_whitelist[i]))
			return TRUE;
	}

	return FALSE;
}

static BOOL is_eraser(const char *name, const char *type)
{
	if (name && match_token(name, "eraser"))
		return TRUE;
	if (type && match_token(type, "eraser"))
		return TRUE;
	return FALSE;
}
#undef BOOL
#undef TRUE
#undef FALSE
/* end code copied from wine */

void GHOST_WindowX11::initXInputDevices()
{
	static XErrorHandler old_handler = (XErrorHandler) 0 ;
	XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);

	if(version && (version != (XExtensionVersion*)NoSuchExtension)) {
		if(version->present) {
			int device_count;
			XDeviceInfo* device_info = XListInputDevices(m_display, &device_count);
			m_xtablet.StylusDevice = NULL;
			m_xtablet.EraserDevice = NULL;
			m_xtablet.CommonData.Active= GHOST_kTabletModeNone;

			/* Install our error handler to override Xlib's termination behavior */
			old_handler = XSetErrorHandler(ApplicationErrorHandler) ;

			for(int i=0; i<device_count; ++i) {
				char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
				
//				printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);


				if(m_xtablet.StylusDevice==NULL && is_stylus(device_info[i].name, device_type)) {
//					printf("\tfound stylus\n");
					m_xtablet.StylusID= device_info[i].id;
					m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);

					if (m_xtablet.StylusDevice != NULL) {
						/* Find how many pressure levels tablet has */
						XAnyClassPtr ici = device_info[i].inputclassinfo;
						for(int j=0; j<m_xtablet.StylusDevice->num_classes; ++j) {
							if(ici->c_class==ValuatorClass) {
//								printf("\t\tfound ValuatorClass\n");
								XValuatorInfo* xvi = (XValuatorInfo*)ici;
								m_xtablet.PressureLevels = xvi->axes[2].max_value;
							
								/* this is assuming that the tablet has the same tilt resolution in both
								 * positive and negative directions. It would be rather weird if it didn't.. */
								m_xtablet.XtiltLevels = xvi->axes[3].max_value;
								m_xtablet.YtiltLevels = xvi->axes[4].max_value;
								break;
							}
						
							ici = (XAnyClassPtr)(((char *)ici) + ici->length);
						}
					} else {
 						m_xtablet.StylusID= 0;
					}
				}
				else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) {
//					printf("\tfound eraser\n");
					m_xtablet.EraserID= device_info[i].id;
					m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
					if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID= 0;
				}

				if(device_type) {
					XFree((void*)device_type);
				}
			}

			/* Restore handler */
			(void) XSetErrorHandler(old_handler) ;

			XFreeDeviceList(device_info);


			XEventClass xevents[10], ev;
			int dcount = 0;

			if(m_xtablet.StylusDevice) {
				DeviceMotionNotify(m_xtablet.StylusDevice, m_xtablet.MotionEvent, ev);
				if(ev) xevents[dcount++] = ev;
				ProximityIn(m_xtablet.StylusDevice, m_xtablet.ProxInEvent, ev);
				if(ev) xevents[dcount++] = ev;
				ProximityOut(m_xtablet.StylusDevice, m_xtablet.ProxOutEvent, ev);
				if(ev) xevents[dcount++] = ev;
			}
			if(m_xtablet.EraserDevice) {
				DeviceMotionNotify(m_xtablet.EraserDevice, m_xtablet.MotionEvent, ev);
				if(ev) xevents[dcount++] = ev;
				ProximityIn(m_xtablet.EraserDevice, m_xtablet.ProxInEvent, ev);
				if(ev) xevents[dcount++] = ev;
				ProximityOut(m_xtablet.EraserDevice, m_xtablet.ProxOutEvent, ev);
				if(ev) xevents[dcount++] = ev;
			}

			XSelectExtensionEvent(m_display, m_window, xevents, dcount);
		}
		XFree(version);
	}
}

#endif /* WITH_X11_XINPUT */

	Window 
GHOST_WindowX11::
getXWindow(
){
	return m_window;
}

	bool 
GHOST_WindowX11::
getValid(
) const {
	return m_valid_setup;
}

	void 
GHOST_WindowX11::
setTitle(
	const STR_String& title
){
	Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
	Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
	XChangeProperty(m_display, m_window,
	                name, utf8str, 8, PropModeReplace,
	                (const unsigned char*) title.ReadPtr(),
	                title.Length());

// This should convert to valid x11 string
//  and getTitle would need matching change
	XStoreName(m_display,m_window,title);

	XFlush(m_display);
}

	void 
GHOST_WindowX11::
getTitle(
	STR_String& title
) const {
	char *name = NULL;
	
	XFetchName(m_display,m_window,&name);
	title= name?name:"untitled";
	XFree(name);
}
	
	void 
GHOST_WindowX11::
getWindowBounds(
	GHOST_Rect& bounds
) const {
		// Getting the window bounds under X11 is not
		// really supported (nor should it be desired).
	getClientBounds(bounds);
}

	void 
GHOST_WindowX11::
getClientBounds(
	GHOST_Rect& bounds
) const {
	Window root_return;
	int x_return,y_return;
	unsigned int w_return,h_return,border_w_return,depth_return;
	GHOST_TInt32 screen_x, screen_y;
	
	XGetGeometry(m_display,m_window,&root_return,&x_return,&y_return,
		&w_return,&h_return,&border_w_return,&depth_return);

	clientToScreen(0, 0, screen_x, screen_y);
	
	bounds.m_l = screen_x;
	bounds.m_r = bounds.m_l + w_return;
	bounds.m_t = screen_y;
	bounds.m_b = bounds.m_t + h_return;

}

	GHOST_TSuccess 
GHOST_WindowX11::
setClientWidth(
	GHOST_TUns32 width
){	
	XWindowChanges values;
	unsigned int value_mask= CWWidth;		
	values.width = width;
	XConfigureWindow(m_display,m_window,value_mask,&values);

	return GHOST_kSuccess;
}

	GHOST_TSuccess 
GHOST_WindowX11::
setClientHeight(
	GHOST_TUns32 height
){
	XWindowChanges values;
	unsigned int value_mask= CWHeight;		
	values.height = height;
	XConfigureWindow(m_display,m_window,value_mask,&values);
	return GHOST_kSuccess;

}

	GHOST_TSuccess 
GHOST_WindowX11::
setClientSize(
	GHOST_TUns32 width,
	GHOST_TUns32 height
){
	XWindowChanges values;
	unsigned int value_mask= CWWidth | CWHeight;		
	values.width = width;
	values.height = height;
	XConfigureWindow(m_display,m_window,value_mask,&values);
	return GHOST_kSuccess;

}	

	void 
GHOST_WindowX11::
screenToClient(
	GHOST_TInt32 inX,
	GHOST_TInt32 inY,
	GHOST_TInt32& outX,
	GHOST_TInt32& outY
) const {
	// This is correct!

	int ax,ay;
	Window temp;

	XTranslateCoordinates(
			m_display,
			RootWindow(m_display, m_visual->screen),
			m_window,
			inX,
			inY,
			&ax,
			&ay,
			&temp
		);
	outX = ax;
	outY = ay;
}
		 
	void 
GHOST_WindowX11::
clientToScreen(
	GHOST_TInt32 inX,
	GHOST_TInt32 inY,
	GHOST_TInt32& outX,
	GHOST_TInt32& outY
) const {
	int ax,ay;
	Window temp;

	XTranslateCoordinates(
			m_display,
			m_window,
			RootWindow(m_display, m_visual->screen),
			inX,
			inY,
			&ax,
			&ay,
			&temp
		);
	outX = ax;
	outY = ay;
}

void GHOST_WindowX11::icccmSetState(int state)
{
	XEvent xev;

	if (state != IconicState)
		return;

	xev.xclient.type = ClientMessage;
	xev.xclient.serial = 0;
	xev.xclient.send_event = True;
	xev.xclient.display = m_display;
	xev.xclient.window = m_window;
	xev.xclient.format = 32;
	xev.xclient.message_type = m_system->m_wm_change_state;
	xev.xclient.data.l[0] = state;
	XSendEvent (m_display, RootWindow(m_display, DefaultScreen(m_display)),
		False, SubstructureNotifyMask | SubstructureRedirectMask, &xev);
}

int GHOST_WindowX11::icccmGetState(void) const
{
	unsigned char *prop_ret;
	unsigned long bytes_after, num_ret;
	Atom type_ret;
	int format_ret, st;

	prop_ret = NULL;
	st = XGetWindowProperty(m_display, m_window, m_system->m_wm_state, 0,
			0x7fffffff, False, m_system->m_wm_state, &type_ret,
			&format_ret, &num_ret, &bytes_after, &prop_ret);

	if ((st == Success) && (prop_ret) && (num_ret == 2))
		st = prop_ret[0];
	else
		st = NormalState;

	if (prop_ret)
		XFree(prop_ret);
	return (st);
}

void GHOST_WindowX11::netwmMaximized(bool set)
{
	XEvent xev;

	xev.xclient.type = ClientMessage;
	xev.xclient.serial = 0;
	xev.xclient.send_event = True;
	xev.xclient.window = m_window;
	xev.xclient.message_type = m_system->m_net_state;
	xev.xclient.format = 32;

	if (set == True)
		xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
	else
		xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;

	xev.xclient.data.l[1] = m_system->m_net_max_horz;
	xev.xclient.data.l[2] = m_system->m_net_max_vert;
	xev.xclient.data.l[3] = 0;
	xev.xclient.data.l[4] = 0;
	XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
		False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}

bool GHOST_WindowX11::netwmIsMaximized(void) const
{
	unsigned char *prop_ret;
	unsigned long bytes_after, num_ret, i;
	Atom type_ret;
	bool st;
	int format_ret, ret, count;

	prop_ret = NULL;
	st = False;
	ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
			0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
			&num_ret, &bytes_after, &prop_ret);
	if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
		count = 0;
		for (i = 0; i < num_ret; i++) {
			if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_horz)
				count++;
			if (((unsigned long *) prop_ret)[i] == m_system->m_net_max_vert)
				count++;
			if (count == 2) {
				st = True;
				break;
			}
		}
	}

	if (prop_ret)
		XFree(prop_ret);
	return (st);
}

void GHOST_WindowX11::netwmFullScreen(bool set)
{
	XEvent xev;

	xev.xclient.type = ClientMessage;
	xev.xclient.serial = 0;
	xev.xclient.send_event = True;
	xev.xclient.window = m_window;
	xev.xclient.message_type = m_system->m_net_state;
	xev.xclient.format = 32;

	if (set == True)
		xev.xclient.data.l[0] = _NET_WM_STATE_ADD;
	else
		xev.xclient.data.l[0] = _NET_WM_STATE_REMOVE;

	xev.xclient.data.l[1] = m_system->m_net_fullscreen;
	xev.xclient.data.l[2] = 0;
	xev.xclient.data.l[3] = 0;
	xev.xclient.data.l[4] = 0;
	XSendEvent(m_display, RootWindow(m_display, DefaultScreen(m_display)),
		False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}

bool GHOST_WindowX11::netwmIsFullScreen(void) const
{
	unsigned char *prop_ret;
	unsigned long bytes_after, num_ret, i;
	Atom type_ret;
	bool st;
	int format_ret, ret;

	prop_ret = NULL;
	st = False;
	ret = XGetWindowProperty(m_display, m_window, m_system->m_net_state, 0,
			0x7fffffff, False, XA_ATOM, &type_ret, &format_ret,
			&num_ret, &bytes_after, &prop_ret);
	if ((ret == Success) && (prop_ret) && (format_ret == 32)) {
		for (i = 0; i < num_ret; i++) {
			if (((unsigned long *) prop_ret)[i] == m_system->m_net_fullscreen) {
				st = True;
				break;
			}
		}
	}

	if (prop_ret)
		XFree(prop_ret);
	return (st);
}

void GHOST_WindowX11::motifFullScreen(bool set)
{
	MotifWmHints hints;

	hints.flags = MWM_HINTS_DECORATIONS;
	if (set == True)
		hints.decorations = 0;
	else
		hints.decorations = 1;

	XChangeProperty(m_display, m_window, m_system->m_motif,
			m_system->m_motif, 32, PropModeReplace,
			(unsigned char *) &hints, 4);
}

bool GHOST_WindowX11::motifIsFullScreen(void) const
{
	unsigned char *prop_ret;
	unsigned long bytes_after, num_ret;
	MotifWmHints *hints;
	Atom type_ret;
	bool state;
	int format_ret, st;

	prop_ret = NULL;
	state = False;
	st = XGetWindowProperty(m_display, m_window, m_system->m_motif, 0,
				0x7fffffff, False, m_system->m_motif,
				&type_ret, &format_ret, &num_ret,
				&bytes_after, &prop_ret);
	if ((st == Success) && (prop_ret)) {
		hints = (MotifWmHints *) prop_ret;
		if (hints->flags & MWM_HINTS_DECORATIONS) {
			if (!hints->decorations)
				state = True;
		}
	}

	if (prop_ret)
		XFree(prop_ret);
	return (state);
}

GHOST_TWindowState GHOST_WindowX11::getState() const
{
	GHOST_TWindowState state_ret;
	int state;

	state_ret = GHOST_kWindowStateNormal;
	state = icccmGetState();
	/*
	 * In the Iconic and Withdrawn state, the window
	 * is unmaped, so only need return a Minimized state.
	 */
	if ((state == IconicState) || (state == WithdrawnState))
		state_ret = GHOST_kWindowStateMinimized;
	else if (netwmIsMaximized() == True)
		state_ret = GHOST_kWindowStateMaximized;
	else if (netwmIsFullScreen() == True)
		state_ret = GHOST_kWindowStateFullScreen;
	else if (motifIsFullScreen() == True)
		state_ret = GHOST_kWindowStateFullScreen;
	return (state_ret);
}

GHOST_TSuccess GHOST_WindowX11::setState(GHOST_TWindowState state)
{
	GHOST_TWindowState cur_state;
	bool is_max, is_full, is_motif_full;

	cur_state = getState();
        if (state == (int)cur_state)
		return GHOST_kSuccess;

	if (cur_state != GHOST_kWindowStateMinimized) {
		/*
		 * The window don't have this property's
		 * if it's not mapped.
		 */
		is_max = netwmIsMaximized();
		is_full = netwmIsFullScreen();
	}
	else {
		is_max = False;
		is_full = False;
	}

	is_motif_full = motifIsFullScreen();

	if (state == GHOST_kWindowStateNormal)
		state = m_normal_state;

	if (state == GHOST_kWindowStateNormal) {
		if (is_max == True)
			netwmMaximized(False);
		if (is_full == True)
			netwmFullScreen(False);
		if (is_motif_full == True)
			motifFullScreen(False);
		icccmSetState(NormalState);
		return (GHOST_kSuccess);
	}

	if (state == GHOST_kWindowStateFullScreen) {
		/*
		 * We can't change to full screen if the window
		 * isn't mapped.
		 */
		if (cur_state == GHOST_kWindowStateMinimized)
			return (GHOST_kFailure);

		m_normal_state = cur_state;

		if (is_max == True)
			netwmMaximized(False);
		if (is_full == False)
			netwmFullScreen(True);
		if (is_motif_full == False)
			motifFullScreen(True);
		return (GHOST_kSuccess);
	}

	if (state == GHOST_kWindowStateMaximized) {
		/*
		 * We can't change to Maximized if the window
		 * isn't mapped.
		 */
		if (cur_state == GHOST_kWindowStateMinimized)
			return (GHOST_kFailure);

		if (is_full == True)
			netwmFullScreen(False);
		if (is_motif_full == True)
			motifFullScreen(False);
		if (is_max == False)
			netwmMaximized(True);
		return (GHOST_kSuccess);
	}

	if (state == GHOST_kWindowStateMinimized) {
		/*
		 * The window manager need save the current state of
		 * the window (maximized, full screen, etc).
		 */
		icccmSetState(IconicState);
		return (GHOST_kSuccess);
	}

	return (GHOST_kFailure);
}

#include <iostream>
using namespace std;

	GHOST_TSuccess 
GHOST_WindowX11::
setOrder(
	GHOST_TWindowOrder order
){
	if (order == GHOST_kWindowOrderTop) {
		XWindowAttributes attr;	  
		Atom atom;

		/* We use both XRaiseWindow and _NET_ACTIVE_WINDOW, since some
		   window managers ignore the former (e.g. kwin from kde) and others
		   don't implement the latter (e.g. fluxbox pre 0.9.9) */

		XRaiseWindow(m_display, m_window);

		atom = XInternAtom(m_display, "_NET_ACTIVE_WINDOW", True);

		if (atom != None) {
			Window root;
			XEvent xev;
			long eventmask;

			xev.xclient.type = ClientMessage;
			xev.xclient.serial = 0;
			xev.xclient.send_event = True;
			xev.xclient.window = m_window;
			xev.xclient.message_type = atom;

			xev.xclient.format = 32;
			xev.xclient.data.l[0] = 1;
			xev.xclient.data.l[1] = CurrentTime;
			xev.xclient.data.l[2] = m_window;
			xev.xclient.data.l[3] = 0;
			xev.xclient.data.l[4] = 0;

			root = RootWindow(m_display, m_visual->screen),
			eventmask = SubstructureRedirectMask | SubstructureNotifyMask;

			XSendEvent(m_display, root, False, eventmask, &xev);
		}

		XGetWindowAttributes(m_display, m_window, &attr);

		/* iconized windows give bad match error */
		if (attr.map_state == IsViewable)
			XSetInputFocus(m_display, m_window, RevertToPointerRoot,
						 CurrentTime);
		XFlush(m_display);
	} else if (order == GHOST_kWindowOrderBottom) {
		XLowerWindow(m_display,m_window);
		XFlush(m_display);
	} else {
		return GHOST_kFailure;
	}
	
	return GHOST_kSuccess;
}

	GHOST_TSuccess 
GHOST_WindowX11::
swapBuffers(
){
	if (getDrawingContextType() == GHOST_kDrawingContextTypeOpenGL) {
		glXSwapBuffers(m_display,m_window);
		return GHOST_kSuccess;
	} else {
		return GHOST_kFailure;
	}
}

	GHOST_TSuccess 
GHOST_WindowX11::
activateDrawingContext(
){
	if (m_context !=NULL) {
		glXMakeCurrent(m_display, m_window,m_context);						
		return GHOST_kSuccess;
	} 
	return GHOST_kFailure;
}

 	GHOST_TSuccess 
GHOST_WindowX11::
invalidate(
){
 	
	// So the idea of this function is to generate an expose event
	// for the window.
	// Unfortunately X does not handle expose events for you and 
	// it is the client's job to refresh the dirty part of the window.
	// We need to queue up invalidate calls and generate GHOST events 
	// for them in the system.

	// We implement this by setting a boolean in this class to concatenate 
	// all such calls into a single event for this window.

	// At the same time we queue the dirty windows in the system class
	// and generate events for them at the next processEvents call.

	if (m_invalid_window == false) {
		m_system->addDirtyWindow(this);
		m_invalid_window = true;
	} 
 
	return GHOST_kSuccess;
}

/**
 * called by the X11 system implementation when expose events
 * for the window have been pushed onto the GHOST queue
 */
 
	void
GHOST_WindowX11::
validate(
){
	m_invalid_window = false;
}	
 
 
/**
 * Destructor.
 * Closes the window and disposes resources allocated.
 */

GHOST_WindowX11::
~GHOST_WindowX11(
){
	static Atom Primary_atom, Clipboard_atom;
	Window p_owner, c_owner;
	/*Change the owner of the Atoms to None if we are the owner*/
	Primary_atom = XInternAtom(m_display, "PRIMARY", False);
	Clipboard_atom = XInternAtom(m_display, "CLIPBOARD", False);
	
	p_owner = XGetSelectionOwner(m_display, Primary_atom);
	c_owner = XGetSelectionOwner(m_display, Clipboard_atom);
	
	std::map<unsigned int, Cursor>::iterator it = m_standard_cursors.begin();
	for (; it != m_standard_cursors.end(); it++) {
		XFreeCursor(m_display, it->second);
	}

	if (m_empty_cursor) {
		XFreeCursor(m_display, m_empty_cursor);
	}
	if (m_custom_cursor) {
		XFreeCursor(m_display, m_custom_cursor);
	}

#ifdef WITH_X11_XINPUT
	/* close tablet devices */
	if(m_xtablet.StylusDevice)
		XCloseDevice(m_display, m_xtablet.StylusDevice);
	
	if(m_xtablet.EraserDevice)
		XCloseDevice(m_display, m_xtablet.EraserDevice);
#endif /* WITH_X11_XINPUT */

	if (m_context != s_firstContext) {
		glXDestroyContext(m_display, m_context);
	}
	
	if (p_owner == m_window) {
		XSetSelectionOwner(m_display, Primary_atom, None, CurrentTime);
	}
	if (c_owner == m_window) {
		XSetSelectionOwner(m_display, Clipboard_atom, None, CurrentTime);
	}
	
	XDestroyWindow(m_display, m_window);
	XFree(m_visual);
}




/**
 * Tries to install a rendering context in this window.
 * @param type	The type of rendering context installed.
 * @return Indication as to whether installation has succeeded.
 */
	GHOST_TSuccess 
GHOST_WindowX11::
installDrawingContext(
	GHOST_TDrawingContextType type
){
	// only support openGL for now.
	GHOST_TSuccess success;
	switch (type) {
	case GHOST_kDrawingContextTypeOpenGL:
		m_context = glXCreateContext(m_display, m_visual, s_firstContext, True);
		if (m_context !=NULL) {
			if (!s_firstContext) {
				s_firstContext = m_context;
			}
			glXMakeCurrent(m_display, m_window,m_context);						
			success = GHOST_kSuccess;
		} else {
			success = GHOST_kFailure;
		}

		break;

	case GHOST_kDrawingContextTypeNone:
		success = GHOST_kSuccess;
		break;

	default:
		success = GHOST_kFailure;
	}
	return success;
}



/**
 * Removes the current drawing context.
 * @return Indication as to whether removal has succeeded.
 */
	GHOST_TSuccess 
GHOST_WindowX11::
removeDrawingContext(
){
	GHOST_TSuccess success;

	if (m_context != NULL) {
		glXDestroyContext(m_display, m_context);
		success = GHOST_kSuccess;
	} else {
		success = GHOST_kFailure;
	}
	return success;	
}


	Cursor
GHOST_WindowX11::
getStandardCursor(
	GHOST_TStandardCursor g_cursor
){
	unsigned int xcursor_id;

#define GtoX(gcurs, xcurs)	case gcurs: xcursor_id = xcurs
	switch (g_cursor) {
	GtoX(GHOST_kStandardCursorRightArrow, XC_arrow); break;
	GtoX(GHOST_kStandardCursorLeftArrow, XC_top_left_arrow); break;
	GtoX(GHOST_kStandardCursorInfo, XC_hand1); break;
	GtoX(GHOST_kStandardCursorDestroy, XC_pirate); break;
	GtoX(GHOST_kStandardCursorHelp, XC_question_arrow); break; 
	GtoX(GHOST_kStandardCursorCycle, XC_exchange); break;
	GtoX(GHOST_kStandardCursorSpray, XC_spraycan); break;
	GtoX(GHOST_kStandardCursorWait, XC_watch); break;
	GtoX(GHOST_kStandardCursorText, XC_xterm); break;
	GtoX(GHOST_kStandardCursorCrosshair, XC_crosshair); break;
	GtoX(GHOST_kStandardCursorUpDown, XC_sb_v_double_arrow); break;
	GtoX(GHOST_kStandardCursorLeftRight, XC_sb_h_double_arrow); break;
	GtoX(GHOST_kStandardCursorTopSide, XC_top_side); break;
	GtoX(GHOST_kStandardCursorBottomSide, XC_bottom_side); break;
	GtoX(GHOST_kStandardCursorLeftSide, XC_left_side); break;
	GtoX(GHOST_kStandardCursorRightSide, XC_right_side); break;
	GtoX(GHOST_kStandardCursorTopLeftCorner, XC_top_left_corner); break;
	GtoX(GHOST_kStandardCursorTopRightCorner, XC_top_right_corner); break;
	GtoX(GHOST_kStandardCursorBottomRightCorner, XC_bottom_right_corner); break;
	GtoX(GHOST_kStandardCursorBottomLeftCorner, XC_bottom_left_corner); break;
	GtoX(GHOST_kStandardCursorPencil, XC_pencil); break;
	GtoX(GHOST_kStandardCursorCopy, XC_arrow); break;
	default:
		xcursor_id = 0;
	}
#undef GtoX

	if (xcursor_id) {
		Cursor xcursor = m_standard_cursors[xcursor_id];
		
		if (!xcursor) {
			xcursor = XCreateFontCursor(m_display, xcursor_id);

			m_standard_cursors[xcursor_id] = xcursor;
		}
		
		return xcursor;
	} else {
		return None;
	}
}

	Cursor 
GHOST_WindowX11::
getEmptyCursor(
) {
	if (!m_empty_cursor) {
		Pixmap blank;
		XColor dummy;
		char data[1] = {0};
			
		/* make a blank cursor */
		blank = XCreateBitmapFromData (
			m_display, 
			RootWindow(m_display,DefaultScreen(m_display)),
			data, 1, 1
		);

		m_empty_cursor = XCreatePixmapCursor(m_display, blank, blank, &dummy, &dummy, 0, 0);
		XFreePixmap(m_display, blank);
	}

	return m_empty_cursor;
}

	GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorVisibility(
	bool visible
){
	Cursor xcursor;
	
	if (visible) {
		xcursor = getStandardCursor( getCursorShape() );
	} else {
		xcursor = getEmptyCursor();
	}

	XDefineCursor(m_display, m_window, xcursor);
	XFlush(m_display);
	
	return GHOST_kSuccess;
}

	GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorGrab(
	GHOST_TGrabCursorMode mode
){
	if(mode != GHOST_kGrabDisable) {
		if(mode != GHOST_kGrabNormal) {
			m_system->getCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
			setCursorGrabAccum(0, 0);

			if(mode == GHOST_kGrabHide)
				setWindowCursorVisibility(false);

		}
#ifdef GHOST_X11_GRAB
		XGrabPointer(m_display, m_window, False, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
#endif
	}
	else {
		if (m_cursorGrab==GHOST_kGrabHide) {
			m_system->setCursorPosition(m_cursorGrabInitPos[0], m_cursorGrabInitPos[1]);
			setWindowCursorVisibility(true);
		}

		if(m_cursorGrab != GHOST_kGrabNormal) {
			/* use to generate a mouse move event, otherwise the last event
			 * blender gets can be outside the screen causing menus not to show
			 * properly unless the user moves the mouse */
			XWarpPointer(m_display,None,None,0,0,0,0,0,0);
		}

		/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
		setCursorGrabAccum(0, 0);
		m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
#ifdef GHOST_X11_GRAB
		XUngrabPointer(m_display, CurrentTime);
#endif
	}

	XFlush(m_display);
	
	return GHOST_kSuccess;
}

	GHOST_TSuccess
GHOST_WindowX11::
setWindowCursorShape(
	GHOST_TStandardCursor shape
){
	Cursor xcursor = getStandardCursor( shape );
	
	XDefineCursor(m_display, m_window, xcursor);
	XFlush(m_display);

	return GHOST_kSuccess;
}

	GHOST_TSuccess
GHOST_WindowX11::
setWindowCustomCursorShape(
	GHOST_TUns8 bitmap[16][2], 
	GHOST_TUns8 mask[16][2], 
	int hotX, 
	int hotY
){

setWindowCustomCursorShape((GHOST_TUns8*)bitmap, (GHOST_TUns8*)mask, 
									16, 16, hotX, hotY, 0, 1);
	return GHOST_kSuccess;
}

	GHOST_TSuccess
GHOST_WindowX11::
setWindowCustomCursorShape(	
	GHOST_TUns8 *bitmap, 
	GHOST_TUns8 *mask, 
	int sizex, 
	int sizey, 
	int hotX, 
	int hotY, 
	int fg_color, 
	int bg_color
){
	Colormap colormap= DefaultColormap(m_display, DefaultScreen(m_display));
	Pixmap bitmap_pix, mask_pix;
	XColor fg, bg;
	
	if(XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
	if(XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;

	if (m_custom_cursor) {
		XFreeCursor(m_display, m_custom_cursor);
	}

	bitmap_pix = XCreateBitmapFromData(m_display, m_window, (char*) bitmap, sizex, sizey);
	mask_pix = XCreateBitmapFromData(m_display, m_window, (char*) mask, sizex, sizey);
		
	m_custom_cursor = XCreatePixmapCursor(m_display, bitmap_pix, mask_pix, &fg, &bg, hotX, hotY);
	XDefineCursor(m_display, m_window, m_custom_cursor);
	XFlush(m_display);
	
	XFreePixmap(m_display, bitmap_pix);
	XFreePixmap(m_display, mask_pix);

    XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
    XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);

	return GHOST_kSuccess;
}

/*

void glutCustomCursor(char *data1, char *data2, int size)
{
	Pixmap source, mask;
	Cursor cursor;
	XColor fg, bg;
	
	if(XAllocNamedColor(__glutDisplay, DefaultColormap(__glutDisplay, __glutScreen),
		"White", &fg, &fg) == 0) return;
	if(XAllocNamedColor(__glutDisplay, DefaultColormap(__glutDisplay, __glutScreen),
		"Red", &bg, &bg) == 0) return;


	source= XCreateBitmapFromData(__glutDisplay, xdraw, data2, size, size);
	mask= XCreateBitmapFromData(__glutDisplay, xdraw, data1, size, size);
		
	cursor= XCreatePixmapCursor(__glutDisplay, source, mask, &fg, &bg, 7, 7);
		
	XFreePixmap(__glutDisplay, source);
	XFreePixmap(__glutDisplay, mask);
		
	XDefineCursor(__glutDisplay, xdraw, cursor);
}

*/
